home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / cmds / as / sprite / RCS / app.c,v < prev    next >
Encoding:
Text File  |  1991-08-27  |  8.3 KB  |  464 lines

  1. head     1.3;
  2. branch   ;
  3. access   ;
  4. symbols  ;
  5. locks    ; strict;
  6. comment  @ * @;
  7.  
  8.  
  9. 1.3
  10. date     91.08.26.23.31.49;  author rab;  state Exp;
  11. branches ;
  12. next     1.2;
  13.  
  14. 1.2
  15. date     90.06.28.15.24.55;  author rab;  state Exp;
  16. branches ;
  17. next     1.1;
  18.  
  19. 1.1
  20. date     90.02.07.13.11.40;  author rab;  state Exp;
  21. branches ;
  22. next     ;
  23.  
  24.  
  25. desc
  26. @@
  27.  
  28.  
  29. 1.3
  30. log
  31. @*** empty log message ***
  32. @
  33. text
  34. @/* This is the Assembler Pre-Processor
  35.    Copyright (C) 1987 Free Software Foundation, Inc.
  36.  
  37. This file is part of GAS, the GNU Assembler.
  38.  
  39. GAS is free software; you can redistribute it and/or modify
  40. it under the terms of the GNU General Public License as published by
  41. the Free Software Foundation; either version 1, or (at your option)
  42. any later version.
  43.  
  44. GAS is distributed in the hope that it will be useful,
  45. but WITHOUT ANY WARRANTY; without even the implied warranty of
  46. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  47. GNU General Public License for more details.
  48.  
  49. You should have received a copy of the GNU General Public License
  50. along with GAS; see the file COPYING.  If not, write to
  51. the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  52.  
  53. /* App, the assembler pre-processor.  This pre-processor strips out excess
  54.    spaces, turns single-quoted characters into a decimal constant, and turns
  55.    # <number> <filename> <garbage> into a .line <number>;.file <filename> pair.
  56.    This needs better error-handling.
  57.  */
  58. #include <stdio.h>
  59. #ifdef USG
  60. #define bzero(s,n) memset(s,0,n)
  61. #endif
  62.  
  63. static char    lex [256];
  64. static char    symbol_chars[] = 
  65.     "$._ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
  66.  
  67. extern char comment_chars[];
  68. extern char line_comment_chars[];
  69.  
  70. #define LEX_IS_SYMBOL_COMPONENT        (1)
  71. #define LEX_IS_WHITESPACE        (2)
  72. #define LEX_IS_LINE_SEPERATOR        (4)
  73. #define LEX_IS_COMMENT_START        (8)    /* JF added these two */
  74. #define LEX_IS_LINE_COMMENT_START    (16)
  75. #define IS_SYMBOL_COMPONENT(c)        (lex [c] & LEX_IS_SYMBOL_COMPONENT)
  76. #define IS_WHITESPACE(c)        (lex [c] & LEX_IS_WHITESPACE)
  77. #define IS_LINE_SEPERATOR(c)        (lex [c] & LEX_IS_LINE_SEPERATOR)
  78. #define IS_COMMENT(c)            (lex [c] & LEX_IS_COMMENT_START)
  79. #define IS_LINE_COMMENT(c)        (lex [c] & LEX_IS_LINE_COMMENT_START)
  80.  
  81. void
  82. do_scrub_begin()
  83. {
  84.     char *p;
  85.  
  86.     bzero (lex, sizeof(lex));        /* Trust NOBODY! */
  87.     lex [' ']        |= LEX_IS_WHITESPACE;
  88.     lex ['\t']        |= LEX_IS_WHITESPACE;
  89.     for (p =symbol_chars;*p;++p)
  90.         lex [*p] |= LEX_IS_SYMBOL_COMPONENT;
  91.     lex ['\n']        |= LEX_IS_LINE_SEPERATOR;
  92. #ifdef DONTDEF
  93.     lex [':']        |= LEX_IS_LINE_SEPERATOR;
  94. #endif
  95.     lex [';']        |= LEX_IS_LINE_SEPERATOR;
  96.     for (p=comment_chars;*p;p++)
  97.         lex[*p] |= LEX_IS_COMMENT_START;
  98.     for (p=line_comment_chars;*p;p++)
  99.         lex[*p] |= LEX_IS_LINE_COMMENT_START;
  100. }
  101.  
  102. FILE *scrub_file;
  103.  
  104. int
  105. scrub_from_file()
  106. {
  107.     return getc(scrub_file);
  108. }
  109.  
  110. void
  111. scrub_to_file(ch)
  112. int ch;
  113. {
  114.     ungetc(ch,scrub_file);
  115. }
  116.  
  117. char *scrub_string;
  118. char *scrub_last_string;
  119.  
  120. int
  121. scrub_from_string()
  122. {
  123.     return scrub_string == scrub_last_string ? EOF : *scrub_string++;
  124. }
  125.  
  126. void
  127. scrub_to_string(ch)
  128. int ch;
  129. {
  130.     *--scrub_string=ch;
  131. }
  132.  
  133. int
  134. do_scrub_next_char(get,unget)
  135. int (*get)();
  136. void (*unget)();
  137. /* FILE *fp; */
  138. {
  139.     /* State 0: beginning of normal line
  140.         1: After first whitespace on normal line (flush more white)
  141.         2: After first non-white on normal line (keep 1white)
  142.         3: after second white on normal line (flush white)
  143.         4: after putting out a .line, put out digits
  144.         5: parsing a string, then go to old-state
  145.         6: putting out \ escape in a "d string.
  146.         7: After putting out a .file string, flush until newline.
  147.         -1: output string in out_string and go to the state in old_state
  148.         -2: flush text until a '*' '/' is seen, then go to state old_state
  149.     */
  150.  
  151.     static state;
  152.     static old_state;
  153.     static char *out_string;
  154.     static char out_buf[20];
  155.     static add_newlines = 0;
  156.     static in_cpp_comment = 0;
  157.     int ch;
  158.  
  159.     if(state==-1) {
  160.         ch= *out_string++;
  161.         if(*out_string==0) {
  162.             state=old_state;
  163.             old_state=3;
  164.         }
  165.         return ch;
  166.     }
  167.     if(state==-2) {
  168.         do ch=(*get)();
  169.         while(ch!=EOF && ch!='\n' && (ch!='*' || (*get)()!='/'));
  170.         if(ch=='\n' || ch==EOF)
  171.             return ch;
  172.         else {
  173.             state=old_state;
  174.             return ' ';
  175.         }
  176.     }
  177.     if(state==4) {
  178.         ch=(*get)();
  179.         if(ch==EOF || (ch>='0' && ch<='9'))
  180.             return ch;
  181.         else {
  182.             while(ch!=EOF && IS_WHITESPACE(ch))
  183.                 ch=(*get)();
  184.             if(ch=='"') {
  185.                 (*unget)(ch);
  186.                 out_string="; .file ";
  187.                 old_state=3;
  188.                 state= -1;
  189.                 return *out_string++;
  190.             } else {
  191.                 while(ch!=EOF && ch!='\n')
  192.                     ch=(*get)();
  193.                 in_cpp_comment = 0;
  194.                 return ch;
  195.             }
  196.         }
  197.     }
  198.     if(state==5) {
  199.         ch=(*get)();
  200.         if(ch=='"') {
  201.             state=old_state;
  202.             if (in_cpp_comment) {
  203.                 while(ch!=EOF && ch!='\n') {
  204.                 ch=(*get)();
  205.                 }
  206.                 (*unget)(ch);
  207.             }
  208.             return '"';
  209.         } else if(ch=='\\') {
  210.             state=6;
  211.             return ch;
  212.         } else if(ch==EOF) {
  213.             as_fatal("End of file in string");
  214.             return 0;
  215.         } else {
  216.             return ch;
  217.         }
  218.     }
  219.     if(state==6) {
  220.         state=5;
  221.         ch=(*get)();
  222.         switch(ch) {
  223.             /* This is neet.  Turn "string
  224.                more string" into "string\n  more string"
  225.              */
  226.         case '\n':
  227.             (*unget)('n');
  228.             add_newlines++;
  229.             return '\\';
  230.  
  231.         case '"':
  232.         case '\\':
  233.         case 'b':
  234.         case 'f':
  235.         case 'n':
  236.         case 'r':
  237.         case 't':
  238.         case '0':
  239.         case '1':
  240.         case '2':
  241.         case '3':
  242.         case '4':
  243.         case '5':
  244.         case '6':
  245.         case '7':
  246.             break;
  247.         default:
  248.             as_warn("Unknown escape '\\%c' in string",ch);
  249.             break;
  250.  
  251.         case EOF:
  252.             as_warn("End of file in string: '\"' inserted");
  253.             return '"';
  254.         }
  255.         return ch;
  256.     }
  257.  
  258.  flushchar:
  259.     ch=(*get)();
  260.     switch(ch) {
  261.     case ' ':
  262.     case '\t':
  263.         do ch=(*get)();
  264.         while(ch!=EOF && IS_WHITESPACE(ch));
  265.         if(ch==EOF)
  266.             return ch;
  267.         if(IS_COMMENT(ch) || (state==0 && IS_LINE_COMMENT(ch)) || ch=='/' || IS_LINE_SEPERATOR(ch)) {
  268.             (*unget)(ch);
  269.             goto flushchar;
  270.         }
  271.         (*unget)(ch);
  272.         if(state==0 || state==2) {
  273.             state++;
  274.             return ' ';
  275.         } else goto flushchar;
  276.  
  277.     case '/':
  278.         ch=(*get)();
  279.         if(ch=='*') {
  280.             for(;;) {
  281.                 do {
  282.                     ch=(*get)();
  283.                     if(ch=='\n')
  284.                         add_newlines++;
  285.                 } while(ch!=EOF && ch!='*');
  286.                 ch=(*get)();
  287.                 if(ch==EOF || ch=='/')
  288.                     break;
  289.                 (*unget)(ch);
  290.             }
  291.             if(ch==EOF)
  292.                 as_warn("End of file in '/' '*' string");
  293.  
  294.             (*unget)(' ');
  295.             goto flushchar;
  296.         } else {
  297.             if(IS_COMMENT('/') || (state==0 && IS_LINE_COMMENT('/'))) {
  298.                     (*unget)(ch);
  299.                 ch='/';
  300.                 goto deal_misc;
  301.             }
  302.             if(ch!=EOF)
  303.                 (*unget)(ch);
  304.             return '/';
  305.         }
  306.         break;
  307.  
  308.     case '"':
  309.         old_state=state;
  310.         state=5;
  311.         return '"';
  312.         break;
  313.  
  314.     case '\'':
  315.         ch=(*get)();
  316.         if(ch==EOF) {
  317.             as_warn("End-of-file after a '");
  318.             ch=0;
  319.         }
  320.         sprintf(out_buf,"(%d)",ch&0xff);
  321.         old_state=state;
  322.         state= -1;
  323.         out_string=out_buf;
  324.         return *out_string++;
  325.  
  326.     case ':':
  327.         if(state!=3)
  328.             state=0;
  329.         return ch;
  330.  
  331.     case '\n':
  332.         if(add_newlines) {
  333.             --add_newlines;
  334.             (*unget)(ch);
  335.         }
  336.     case ';':
  337.         state=0;
  338.         return ch;
  339.  
  340.     default:
  341.     deal_misc:
  342.         if(state==0 && IS_LINE_COMMENT(ch)) {
  343.             do ch=(*get)();
  344.             while(ch!=EOF && IS_WHITESPACE(ch));
  345.             if(ch==EOF) {
  346.                 as_warn("Unexpected EOF in comment");
  347.                 return '\n';
  348.             }
  349.             if(ch<'0' || ch>'9') {
  350.                 do ch=(*get)();
  351.                 while(ch!=EOF && ch!='\n');
  352.                 if(ch==EOF)
  353.                     as_warn("Unexpected EOF in Comment");
  354.                 state=0;
  355.                 return '\n';
  356.             }
  357.             (*unget)(ch);
  358.             old_state=4;
  359.             state= -1;
  360.             out_string=".line ";
  361.             in_cpp_comment = 1;
  362.             return *out_string++;
  363.  
  364.         } else if(IS_COMMENT(ch)) {
  365.             do ch=(*get)();
  366.             while(ch!=EOF && ch!='\n');
  367.             if(ch==EOF)
  368.                 as_warn("Unexpected EOF in comment");
  369.             state=0;
  370.             return '\n';
  371.  
  372.         } else if(state==0) {
  373.             state=2;
  374.             return ch;
  375.         } else if(state==1) {
  376.             state=2;
  377.             return ch;
  378.         } else {
  379.             return ch;
  380.  
  381.         }
  382.     case EOF:
  383.         if(state==0)
  384.             return ch;
  385.         as_warn("End-of-File not at end of a line");
  386.     }
  387.     return -1;
  388. }
  389.  
  390. #ifdef TEST
  391.  
  392. char comment_chars[] = "|";
  393. char line_comment_chars[] = "#";
  394.  
  395. main()
  396. {
  397.     int    ch;
  398.  
  399.     app_begin();
  400.     while((ch=do_scrub_next_char(stdin))!=EOF)
  401.         putc(ch,stdout);
  402. }
  403.  
  404. as_warn(str)
  405. char *str;
  406. {
  407.     fputs(str,stderr);
  408.     putc('\n',stderr);
  409. }
  410. #endif
  411. @
  412.  
  413.  
  414. 1.2
  415. log
  416. @Added some missing opcodes and fixed some misc bugs.
  417. @
  418. text
  419. @d265 1
  420. @
  421.  
  422.  
  423. 1.1
  424. log
  425. @Initial revision
  426. @
  427. text
  428. @d123 1
  429. d135 7
  430. a141 9
  431.         for(;;) {
  432.             do ch=(*get)();
  433.             while(ch!=EOF && ch!='\n' && ch!='*');
  434.             if(ch=='\n' || ch==EOF)
  435.                 return ch;
  436.              ch=(*get)();
  437.              if(ch==EOF || ch=='/')
  438.                  break;
  439.             (*unget)(ch);
  440. a142 2
  441.         state=old_state;
  442.         return ' ';
  443. d154 1
  444. a154 1
  445.                 old_state=7;
  446. d160 1
  447. d169 6
  448. d180 2
  449. a181 4
  450.             as_warn("End of file in string: inserted '\"'");
  451.              state=old_state;
  452.             (*unget)('\n');
  453.             return '"';
  454. a224 7
  455.     if(state==7) {
  456.         do ch= (*get)();
  457.         while(ch!='\n');
  458.         state=0;
  459.         return ch;
  460.     }
  461.  
  462. d327 1
  463. @
  464.